package com.woniu.service.impl;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.MD5;
import com.nimbusds.jose.JOSEException;
import com.woniu.entity.Address;
import com.woniu.entity.Book;
import com.woniu.entity.User;
import com.woniu.entity.UserCart;
import com.woniu.entity.dto.UserDTO;
import com.woniu.mapper.UserMapper;
import com.woniu.service.UserService;
import com.woniu.util.JWTUtil;
import com.woniu.util.ResponseData;
import com.woniu.util.ResponseEnum;
import com.woniu.util.UserContext;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@AllArgsConstructor
public class UserServiceImpl implements UserService {
    private UserMapper userMapper;

    //操作redis：写数据库，获取数据，删除数据
    private StringRedisTemplate redisTemplate;
    private RedisTemplate<String,Object> redisTemplateInit;
    /**
     * 1:根据账号查询用户信息
     * 2:判断用户信息是否存在
     *      不存在：直接返回
     *      存在：继续运行程序
     * 3:对比密码
     *      不成功：直接返回
     *      成功：继续运行程序
     * 4:给该用户创建jwt
     * 5:把jwt存入redis
     * 6:把用户信息返回
     * @param user
     * @return
     */
    @Override
    public ResponseData<?> login(User user) throws JOSEException {
        User useInfo = userMapper.queryUseInfo(user);
        if (useInfo == null){ //用户名为空直接返回错误信息
            return ResponseData.fail(ResponseEnum.LOGIN_ERROR);
        }
        //处于对密码安全性考虑都要给密码加盐值后在加密放入数据库
        // md5(123456 + 盐值)生成密钥,数据库内的默认盐值是在密码后加1a2b3c4d
        String md5 = SecureUtil.md5(user.getPassword() + "1a2b3c4d"); //把输入的密码转成密钥,数据库内密码也是密钥
        if (!useInfo.getPassword().equals(md5)){ //密码对不上直接返回错误信息
            return ResponseData.fail(ResponseEnum.PARAM_ERROR);
        }
        //4:给用户创建jwt
        HashMap<Object, Object> userMap = new HashMap<>();
        userMap.put("id",useInfo.getId());
        userMap.put("account",useInfo.getAccount());
        String jwt = JWTUtil.createJWT(userMap);

        //5把jwt存入redis(redis是一个采用key，value方式存储的数据库)
        //1加入依赖2引用类3配置连接redis的连接信息（yml）
        //参数3是数值，参数4是单位，设置rides内的jwt多久消失
        redisTemplate.opsForValue().set("JWT:"+useInfo.getId(),jwt,15, TimeUnit.DAYS);//key多个单词用：隔开，全部大写

        //6把用户信息和jwt一起返回
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("user",new UserDTO(useInfo));
//        resultMap.put("user",useInfo);
        resultMap.put("jwt",jwt);
        return ResponseData.ok(resultMap); //返回空
    }

    /**
     * 用户添加购物车
     * 1:判断用户是否添加过此书籍
     *      没有：新增
     *      有：修改
     * 2
     * 3:
     * 4:
     * @param id
     * @param buyNum
     * @return
     */
    @Override
    public ResponseData<?> addCart(Integer id, Integer buyNum) throws ParseException {
        UserCart userCartParam = new UserCart();//新建购物车
        userCartParam.setBookId(id);//填入id
        Integer userId = UserContext.getUserId();//得到jwt中的userId

        userCartParam.setUserId(userId);//填入UserID
        UserCart userCartInfo = userMapper.queryUserCart(userCartParam);//根据条件查是否存在

        userCartParam.setBuyNum(userCartInfo == null ? buyNum : buyNum+userCartInfo.getBuyNum());
        //写入最新的价格（从redis中获取）
        Book cacheBook = (Book) redisTemplateInit.opsForHash().get("CACHE:BookServiceImpl:queryBookById", id + "");
        userCartParam.setBuyPrice(cacheBook.getPrice());
        userCartParam.setTotalPrice(userCartParam.getBuyPrice().multiply(new BigDecimal(userCartParam.getBuyNum())));

        if (userCartInfo == null){
            //没有添加过，新增
            userMapper.addUserCart(userCartParam);
        }else {
            //修改
            userCartParam.setId(userCartInfo.getId());
            userMapper.updateUserCart(userCartParam);
        }
        return ResponseData.ok();
    }

    @Override
    public ResponseData<?> queryCartAndAddr() throws ParseException {
        Integer userId = UserContext.getUserId();
        List<Address> addresses = userMapper.queryUserAddr(userId);
        //查询用户购物车
        List<UserCart> userCarts = userMapper.queryUserCarts(userId);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("addresses",addresses);
        resultMap.put("userCarts",userCarts);
        return ResponseData.ok(resultMap);
    }
}
